//
//  BaseService.m
//  Baseproject
//
//  Created by gullmei on 15/9/11.
//  Copyright (c) 2015年 黄定坤. All rights reserved.
//

#import "BaseService.h"
#import  "BaseModel.h"
#import "TypeConversion.h"

#import "NullKiller.h"
 @implementation ResResult

- (id)init {
    self = [super init];
    if (self) {
        _resData = nil;
        _resCode = -1;
        _errMessage = @"";
    }
    
    return self;
}
@end


@implementation BaseService
@synthesize delegate;
@synthesize hostUrl = _hostUrl, paramDict = _paramDict,modelclass   = _modelclass,keyStr = _keyStr , sign = _sign,notificationName = _notificationName,reponseType = _reponseType, httpRequestResultBlock,saveToGlobalData,decodeData,icon = _icon,iconArr = _iconArr,iconKey=_iconKey,iconName = _iconName;

-(id)init
{
    if(self = [super init]){
      
        _paramDict = [[NSMutableDictionary alloc] init];
        _reponseType = TYPE_OBJECT;
    }
    
        return self;
}

+ (instancetype)getObject
{
    BaseService *base = [[self alloc] init];
    return base;
}

- (void)getRequestWithUrl:(NSString *)urlString parameter:(id)param success:(id (^)(id, NSError *))aSuccess
{    
    NSString *url = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = 20;
    //请求设置
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    //告诉AFN，支持接受 text/xml 的数据
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    

    AFSecurityPolicy* securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]]];
    securityPolicy.allowInvalidCertificates = NO;
    manager.securityPolicy = securityPolicy;
    //在header里封装token
    AFHTTPRequestSerializer *requestSerializer =  [AFJSONRequestSerializer serializer];
//    NSDictionary *headerFieldValueDictionary = @{
//                                                 @"Accept":@"application/json",
//                                                 @"Authorization":[NSString stringWithFormat:@"Bearer %@",[[NSUserDefaults standardUserDefaults] objectForKey:@"token"]]
//                                                 };
//    if (headerFieldValueDictionary != nil) {
//        for (NSString *httpHeaderField in headerFieldValueDictionary.allKeys) {
//            NSString *value = headerFieldValueDictionary[httpHeaderField];
//            [requestSerializer setValue:value forHTTPHeaderField:httpHeaderField];
//        }
//    }
    manager.requestSerializer = requestSerializer;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    
    [manager GET:url parameters:param progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable object) {

        NSString *responseString = [[NSString alloc] initWithData:object encoding:NSUTF8StringEncoding];
        NSData *data;
        id responseObject = nil;
        NSError *serializationError = nil;
        data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
        
        responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&serializationError];
        
        int code;
        if ([[responseObject objectForKey:@"status"] integerValue]  == 0) {
            code = 1;
        }else if ([[responseObject objectForKey:@"status"] integerValue]  == 4001) {//token超时
            code = 0;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [[NSNotificationCenter defaultCenter] postNotificationName:TokenTimeoutNotification object:nil];
            });
        }else{
            code = 0;
        }
        [self OnRecvData:responseObject rcode:code];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

        NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
 
        [self OnRecvData:nil rcode:NET_ERROR];
    }];
}


- (void)postRequestWithUrl:(NSString *)urlString parameter:(id)param success:(id (^)(id, NSError *))aSuccess
{
    NSString *url = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = 20;
    //请求设置
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    //告诉AFN，支持接受 text/xml 的数据
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    // AFSecurityPolicy* securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]]];
    //    securityPolicy.allowInvalidCertificates = NO;
    //    manager.securityPolicy = securityPolicy;
    //在header里封装token
    AFHTTPRequestSerializer *requestSerializer =  [AFHTTPRequestSerializer serializer];
    NSDictionary *headerFieldValueDictionary = @{
                                                 @"Content-Type":@"application/json;charset=UTF-8",
                                                 };
    //    application/x-www-form-urlencoded
    if (headerFieldValueDictionary != nil) {
        for (NSString *httpHeaderField in headerFieldValueDictionary.allKeys) {
            NSString *value = headerFieldValueDictionary[httpHeaderField];
            [requestSerializer setValue:value forHTTPHeaderField:httpHeaderField];
        }
    }
    manager.requestSerializer = requestSerializer;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:param];
    dic[@"sign"] = [self md5HexDigest:[self dictToString:param]];
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
    NSString * jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@""];
  
    [manager POST:url parameters:jsonString progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable object) {
        NSString *responseString = [[NSString alloc] initWithData:object encoding:NSUTF8StringEncoding];
        NSData *data;
        id responseObject = nil;
        NSError *serializationError = nil;
        data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
        
        responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&serializationError];
        int code;
        if ([[responseObject objectForKey:@"code"] integerValue]  == 0) {
            code = 1;
        }else if ([[responseObject objectForKey:@"code"] integerValue]  == 9) {//token超时
            code = 0;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [[NSNotificationCenter defaultCenter] postNotificationName:TokenTimeoutNotification object:nil];
            });
        }else{
            code = 0;
        }
        [self OnRecvData:responseObject rcode:code];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
        [self OnRecvData:nil rcode:NET_ERROR];
    }];
}

- (void)postRequestWithUrl:(NSString *)urlString  icon:(UIImage *)icon parameter:(id)param success:(id (^)(id, NSError *))aSuccess name:(NSString *)name
{
    NSString *url = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];//
 
    [manager POST:url parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//         NSData *data = UIImageJPEGRepresentation(_icon, 1.0);
        NSData *data = UIImageJPEGRepresentation([UIImage lubanCompressImage:_icon], 1.0);
        //名字
        NSString *fn = [NSString stringWithFormat:@"%@.png",name];
//        @".png";
        //类型
        [formData appendPartWithFileData:data name:name fileName:fn mimeType:@"png"];
      } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        int code;
        DLog(@"%@",responseObject);
        if ([[responseObject objectForKey:@"status"] integerValue]  == 0) {
            code = 1;
        }else if ([[responseObject objectForKey:@"status"] integerValue]  == 9) {//token超时
            code = 0;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [[NSNotificationCenter defaultCenter] postNotificationName:TokenTimeoutNotification object:nil];
            });
        }else{
            code = 0;
        }
        
        [self OnRecvData:responseObject rcode:code];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self OnRecvData:nil rcode:NET_ERROR];
    }];
}

- (void)postRequestWithUrl:(NSString *)urlString  photoArr:(NSArray *)photoArr parameter:(id)param success:(id (^)(id, NSError *))aSuccess
{
    NSString *url = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    //告诉AFN，支持接受 text/xml 的数据
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    
    AFSecurityPolicy* securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]]];
    securityPolicy.allowInvalidCertificates = NO;
    manager.securityPolicy = securityPolicy;
    //在header里封装token
    AFHTTPRequestSerializer *requestSerializer =  [AFJSONRequestSerializer serializer];
    NSDictionary *headerFieldValueDictionary = @{
                                                 @"Accept":@"application/json",
                                                 @"Authorization":[NSString stringWithFormat:@"Bearer %@",[[NSUserDefaults standardUserDefaults] objectForKey:@"token"]]
                                                 };
    if (headerFieldValueDictionary != nil) {
        for (NSString *httpHeaderField in headerFieldValueDictionary.allKeys) {
            NSString *value = headerFieldValueDictionary[httpHeaderField];
            [requestSerializer setValue:value forHTTPHeaderField:httpHeaderField];
        }
    }
    manager.requestSerializer = requestSerializer;
    
    [manager POST:url parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        for (int i=0; i<photoArr.count; i++) {
            UIImage *image = photoArr[i];
            NSData *data = UIImageJPEGRepresentation([UIImage lubanCompressImage:image], 1.0);
            //名字
            NSString *fn = [NSString stringWithFormat:@"%d.png",i];
            if (_iconName) {
                fn = [NSString stringWithFormat:@"i%@",_iconName];
            }
            //对接的key
//            NSString *idName = [NSString stringWithFormat:@"flie%d",i];
//            if (self.iconKey) {
//                idName = [NSString stringWithFormat:@"%@%d",self.iconKey,i];;
//            }
            NSString *idName = @"image[]";
            //类型
            [formData appendPartWithFileData:data name:idName fileName:fn mimeType:@"jpeg/png"];
        }
    } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        int code;

        if ([[responseObject objectForKey:@"code"] integerValue]  == 0) {
            code = 1;
        }else if ([[responseObject objectForKey:@"code"] integerValue]  == 9) {//token超时
            code = 0;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [[NSNotificationCenter defaultCenter] postNotificationName:TokenTimeoutNotification object:nil];
            });
        }else{
            code = 0;
        }
        [self OnRecvData:responseObject rcode:code];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        [self OnRecvData:nil rcode:NET_ERROR];
    }];
}
#pragma mark - OnRecvData  接受回报处理流程
-(void)OnRecvData:(id)responseObject rcode:(int)code
{
//    @try {
        id resultobject;
        if(code == 1) { //返回正常
            if (self.decodeData){
                resultobject = self.decodeData(responseObject);
            }else if(_reponseType == TYPE_ARRAY){
                NSArray * array  = [responseObject objectForKey:self.keyStr] ;   
                NSMutableArray * list = [[NSMutableArray alloc] init ];
                for ( NSDictionary*   dic in array)
                {
                    BaseModel * model = [_modelclass decodeAndSaveData:dic];
                    [BaseModel printModel:dic];
                    [list addObject:model];
                }
                resultobject = list;
            }else if(_reponseType == TYPE_OTHER){
                NSDictionary * dic = responseObject  ;
                //[BaseModel printModel:dic];
                BaseModel * model = [_modelclass decodeAndSaveData:dic];
                resultobject = model;
            } else{
                NSDictionary * dic = [responseObject objectForKey:self.keyStr];
                if ([[NSString stringWithFormat:@"%@",[responseObject objectForKey:self.keyStr]] isEqualToString:@"<null>"]) {
                    dic = [NSDictionary new];
                }
//                [BaseModel printModel:dic];
                BaseModel * model = [_modelclass decodeAndSaveData:dic];
                resultobject = model;
            }
        }else if(code != NET_ERROR){
            NSString * expTips = [responseObject objectForKey:@"msg"];
            resultobject = expTips;
        }else{
            resultobject = @"网络连接错误";
        }
        
        if(self.saveToGlobalData){
            self.saveToGlobalData(resultobject,code);
        }
        //success
        if (self.delegate && [self.delegate respondsToSelector:@selector(responseWithObject:resultCode:error:)]) {
            [self.delegate responseWithObject:resultobject resultCode:code error:nil];
        } else {
            ResResult * rdata = [[ResResult alloc] init];
            rdata.resData = resultobject;
            rdata.resCode = code;
            [[NSNotificationCenter defaultCenter] postNotificationName:self.notificationName object:rdata];
        }
        
        if(self.httpRequestResultBlock){
            self.httpRequestResultBlock(resultobject ,code);
        }
 
}
#pragma mark - start  启动业务
#pragma mark -
- (void)extracted {
    [self postRequestWithUrl:_hostUrl parameter:_paramDict success:^id(id responseObject, NSError *error) {
        return nil;
    }];
}

-(void)startPostRequest
{
    
    [self extracted];
}
-(void)startGetRequest
{
    [self getRequestWithUrl:_hostUrl parameter:_paramDict success:^id(id responseObject, NSError *error) {
        return nil;
    }];
}

-(void)startUpload:(NSString *)name{
//    [self postRequestWithUrl:_hostUrl icon:_icon parameter:_paramDict success:name  success:^id(id responseObject, NSError *error) {
//        return nil;
//    }];
    [self postRequestWithUrl:_hostUrl icon:_icon parameter:_paramDict success:^id(id responseObject, NSError *error) {
        return nil;
    } name:(NSString *)name];
}
-(void)startUploadPhotoArr{
    [self postRequestWithUrl:_hostUrl photoArr:_iconArr parameter:_paramDict success:^id(id responseObject, NSError *error) {
        
        return nil;
    }];
}

#pragma mark - md5加密  启动业务
- (NSString *)dictToString:(NSDictionary *)dict{
    NSString *deString = @"";
    int i =0;
    NSArray* arr = [dict allKeys];
    arr = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
        NSComparisonResult result = [obj1 compare:obj2];
        return result==NSOrderedDescending;
    }];
    for (NSString *s in arr) {
        if(i ==0){
            if ([[dict objectForKey:s] isKindOfClass:[NSArray class]]) {
                
                NSArray *info = [dict objectForKey:s];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"\"%@\":[",s]];
                
                for (NSDictionary *dic2 in info) {
                    deString = [deString stringByAppendingString:[self dictToString2:dic2]];
                }
                deString = [deString substringToIndex:deString.length-1];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"]"]];
                
            }else {
                deString = [NSString stringWithFormat:@"{\"%@\":\"%@\"",s,[dict objectForKey:s]];
            }
            i=1;
        }else{
            if ([[dict objectForKey:s] isKindOfClass:[NSArray class]]) {
                NSArray *info = [dict objectForKey:s];
                
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@",\"%@\":[",s]];
               
                for (NSDictionary *dic2 in info) {
                    deString = [deString stringByAppendingString:[self dictToString2:dic2]];
                    deString = [deString stringByAppendingString:@","];
                }
                
                deString = [deString substringToIndex:deString.length-1];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"]"]];
            }else {
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@",\"%@\":\"%@\"",s,[dict objectForKey:s]]];
            }
        }
    }
    deString = [NSString stringWithFormat:@"%@}",deString];
    return deString;
}

- (NSString *)dictToString2:(NSDictionary *)dict{
    NSString *deString = @"";
    int i =0;
    NSArray* arr = [dict allKeys];
    arr = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
        NSComparisonResult result = [obj1 compare:obj2];
        return result==NSOrderedDescending;
    }];
    for (NSString *s in arr) {
        if(i ==0){
            if ([[dict objectForKey:s] isKindOfClass:[NSArray class]]) {
                
                NSArray *info = [dict objectForKey:s];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"{\"%@\":[",s]];
                for (NSDictionary *dic2 in info) {
                    deString = [deString stringByAppendingString:[self dictToString3:dic2]];
                    deString = [deString stringByAppendingString:@","];
                }
                deString = [deString substringToIndex:deString.length-1];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"]"]];
                
            }else {
                deString = [NSString stringWithFormat:@"{\"%@\":\"%@\"",s,[dict objectForKey:s]];
            }
            i=1;
        }else{
            if ([[dict objectForKey:s] isKindOfClass:[NSArray class]]) {
                NSArray *info = [dict objectForKey:s];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@",\"%@\":[",s]];
                for (NSDictionary *dic2 in info) {
                    deString = [deString stringByAppendingString:[self dictToString3:dic2]];
                }
                deString = [deString substringToIndex:deString.length-1];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"]"]];
            }else {
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@",\"%@\":\"%@\"",s,[dict objectForKey:s]]];
            }
        }
    }
    deString = [NSString stringWithFormat:@"%@}",deString];
    return deString;
}


- (NSString *)dictToString3:(NSDictionary *)dict{
    NSString *deString = @"";
    int i =0;
    NSArray* arr = [dict allKeys];
    arr = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
        NSComparisonResult result = [obj1 compare:obj2];
        return result==NSOrderedDescending;
    }];
    for (NSString *s in arr) {
        if(i ==0){
            if ([[dict objectForKey:s] isKindOfClass:[NSArray class]]) {
                
                NSArray *info = [dict objectForKey:s];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"\"%@\":[",s]];
                
                for (NSDictionary *dic2 in info) {
                    deString = [deString stringByAppendingString:[self dictToString2:dic2]];
                }
                deString = [deString substringToIndex:deString.length-1];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"]"]];
                
            }else {
                deString = [NSString stringWithFormat:@"{\"%@\":\"%@\"",s,[dict objectForKey:s]];
            }
            i=1;
        }else{
            if ([[dict objectForKey:s] isKindOfClass:[NSArray class]]) {
                NSArray *info = [dict objectForKey:s];
                
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@",\"%@\":[",s]];
                
                for (NSDictionary *dic2 in info) {
                    deString = [deString stringByAppendingString:[self dictToString2:dic2]];
                }
                
                deString = [deString substringToIndex:deString.length-1];
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@"]"]];
            }else {
                deString = [deString stringByAppendingString:[NSString stringWithFormat:@",\"%@\":\"%@\"",s,[dict objectForKey:s]]];
            }
        }
    }
    deString = [NSString stringWithFormat:@"%@}",deString];
    return deString;
}

- (NSString *)md5HexDigest:(NSString*)input
{
    
    input = [NSString stringWithFormat:@"%@HJ.MET.Inv",input];
    const char* str = [input UTF8String];
//    NSString * str = input;
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, strlen(str), result);
    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];//
    
    for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
        [ret appendFormat:@"%02x",result[i]];
    }
    return ret;
}


- (NSString *)jsonStringEncoded:(NSDictionary *)param {
    if ([NSJSONSerialization isValidJSONObject:param]) {
        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:param options:0 error:&error];
        NSString *json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        if (!error) return json;
    }
    return nil;
}

@end
